/*
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package net.sf.l2j.gameserver.util;

import net.sf.l2j.Config;
import net.sf.l2j.gameserver.ThreadPoolManager;
import net.sf.l2j.gameserver.datatables.NpcTable;
import net.sf.l2j.gameserver.datatables.SummonItemsData;
import net.sf.l2j.gameserver.model.L2ItemInstance;
import net.sf.l2j.gameserver.model.L2Summon;
import net.sf.l2j.gameserver.model.L2SummonItem;
import net.sf.l2j.gameserver.model.L2World;
import net.sf.l2j.gameserver.model.actor.instance.L2NpcInstance;
import net.sf.l2j.gameserver.model.actor.instance.L2PcInstance;
import net.sf.l2j.gameserver.model.actor.instance.L2PetInstance;
import net.sf.l2j.gameserver.network.SystemMessageId;
import net.sf.l2j.gameserver.network.serverpackets.MagicSkillLaunched;
import net.sf.l2j.gameserver.network.serverpackets.MagicSkillUser;
import net.sf.l2j.gameserver.network.serverpackets.SystemMessage;
import net.sf.l2j.gameserver.templates.L2NpcTemplate;

public final class Evolve {
	public static final boolean doEvolve(L2PcInstance player,
			L2NpcInstance npc, int itemIdtake, int itemIdgive, int petminlvl) {
		if (itemIdtake == 0 || itemIdgive == 0 || petminlvl == 0)
			return false;
		L2Summon summon = player.getPet();
		if (summon == null || !(summon instanceof L2PetInstance))
			return false;
		L2PetInstance currentPet = (L2PetInstance) summon;
		if (currentPet.isAlikeDead()) {
			Util.handleIllegalPlayerAction(player, "Player " + player.getName()
					+ " tried to use death pet exploit!", Config.DEFAULT_PUNISH);
			player.closeNetConnection(); // kick
			return false;
		}
		L2ItemInstance item = null;
		long petexp = currentPet.getStat().getExp();
		String oldname = currentPet.getName();
		int oldX = currentPet.getX();
		int oldY = currentPet.getY();
		int oldZ = currentPet.getZ();
		L2SummonItem olditem = SummonItemsData.getInstance().getSummonItem(
				itemIdtake);
		if (olditem == null)
			return false;
		int oldnpcID = olditem.getNpcId();
		if (currentPet.getStat().getLevel() < petminlvl
				|| currentPet.getNpcId() != oldnpcID)
			return false;
		L2SummonItem sitem = SummonItemsData.getInstance().getSummonItem(
				itemIdgive);
		if (sitem == null)
			return false;
		int npcID = sitem.getNpcId();
		if (npcID == 0)
			return false;
		L2NpcTemplate npcTemplate = NpcTable.getInstance().getTemplate(npcID);
		currentPet.unSummon(player);
		// deleting old pet item
		// currentPet.destroyControlItem(player, true);
		item = player.getInventory().addItem("Evolve", itemIdgive, 1, player,
				npc);
		// Summoning new pet
		L2PetInstance petSummon = L2PetInstance.spawnPet(npcTemplate, player,
				item);
		if (petSummon == null)
			return false;
		petSummon.getStat().addExp(petexp);
		petSummon.setCurrentHp(petSummon.getMaxHp());
		petSummon.setCurrentMp(petSummon.getMaxMp());
		petSummon.setCurrentFed(petSummon.getMaxFed());
		petSummon.setTitle(player.getName());
		petSummon.setName(oldname);
		petSummon.setRunning();
		petSummon.store();
		player.setPet(petSummon);
		player.sendPacket(new MagicSkillUser(npc, 2046, 1, 1000, 600000));
		player.sendPacket(new SystemMessage(SystemMessageId.SUMMON_A_PET));
		L2World.getInstance().storeObject(petSummon);
		petSummon.spawnMe(oldX, oldY, oldZ);
		// petSummon.startFeed();
		item.setEnchantLevel(petSummon.getLevel());
		ThreadPoolManager.getInstance().scheduleGeneral(
				new EvolveFinalizer(player, petSummon), 900);
		if (petSummon.getCurrentFed() <= 0)
			ThreadPoolManager.getInstance().scheduleGeneral(
					new EvolveFeedWait(player, petSummon), 60000);
		// else
		// petSummon.startFeed();
		return true;
	}

	static final class EvolveFeedWait implements Runnable {
		private final L2PcInstance _activeChar;
		private final L2PetInstance _petSummon;

		EvolveFeedWait(L2PcInstance activeChar, L2PetInstance petSummon) {
			_activeChar = activeChar;
			_petSummon = petSummon;
		}

		public void run() {
			try {
				if (_petSummon.getCurrentFed() <= 0)
					_petSummon.unSummon(_activeChar);
				/*
				 * else _petSummon.startFeed();
				 */
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	static final class EvolveFinalizer implements Runnable {
		private final L2PcInstance _activeChar;
		private final L2PetInstance _petSummon;

		EvolveFinalizer(L2PcInstance activeChar, L2PetInstance petSummon) {
			_activeChar = activeChar;
			_petSummon = petSummon;
		}

		public void run() {
			try {
				_activeChar.sendPacket(new MagicSkillLaunched(_activeChar,
						2046, 1));
				_petSummon.setFollowStatus(true);
				_petSummon.setShowSummonAnimation(false);
			} catch (Throwable e) {
				e.printStackTrace();
			}
		}
	}
}